package com.dxy.df.modules.service.impl;

import com.dxy.df.constants.ConstStrings;
import com.dxy.df.modules.es.ArticleBean;
import com.dxy.df.modules.es.ArticleRepository;
import com.dxy.df.modules.es.IEsSearchService;
import com.dxy.df.core.shiro.ShiroUtils;
import com.dxy.df.utils.UcBeanUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import com.dxy.df.modules.bean.entity.DfArticleEntity;
import com.dxy.df.modules.bean.vo.DfArticleVo;
import com.dxy.df.modules.bean.query.DfArticleQuery;
import com.dxy.df.modules.bean.put.DfArticlePut;
import com.dxy.df.modules.dao.DfArticleMapper;
import com.dxy.df.modules.service.DfArticleService;


/**
 * @author biz@dxy.cn
 * @describe 文章表
 * @date 2019-10-25 16:23:46
 */
@Service
public class DfArticleServiceImpl implements DfArticleService {

	@Autowired
	@Qualifier("articleRepository")
	private ArticleRepository articleRepository;

	@Autowired
	private IEsSearchService esSearchService;

	@Autowired
	private DfArticleMapper dfArticleMapper;

	@Override
	public DfArticleEntity queryObject(DfArticleQuery query){
		return dfArticleMapper.queryObject(query);
	}

	@Override
	public List<DfArticleVo> queryList(DfArticleQuery query){
		List<DfArticleVo> articleVos = dfArticleMapper.queryList(query);
		articleVos.forEach(articleVo ->{
			articleVo.setCommentCount(dfArticleMapper.queryCommentCount(articleVo.getId()));
			articleVo.setLikeCount(dfArticleMapper.queryLikeCount(articleVo.getId()));
		});
		return articleVos;
	}

	@Override
	public int queryTotal(DfArticleQuery query){
		return dfArticleMapper.queryTotal(query);
	}

	@Override
	public void save(DfArticlePut put){
		DfArticleEntity entity = UcBeanUtils.copyPropertiesForDDL(put, DfArticleEntity.class, ConstStrings.ADD);
		entity.setAuthor(entity.getCreateBy());
		entity.setCreateBy(ShiroUtils.getUserAccount());
		entity.setAuthor(ShiroUtils.getUserAccount());
		entity.setUpdateBy(ShiroUtils.getUserAccount());
		dfArticleMapper.save(entity);

		ArticleBean articleBean =  new ArticleBean();
		BeanUtils.copyProperties(put, articleBean);
		articleBean.setId(entity.getId());
		articleRepository.save(articleBean);
	}

	@Override
	public void update(DfArticlePut put){
		DfArticleEntity entity = UcBeanUtils.copyPropertiesForDDL(put, DfArticleEntity.class, "");
		entity.setUpdateBy(ShiroUtils.getUserAccount());
		dfArticleMapper.update(entity);
	}

	@Override
	public void delete(Integer id){
		dfArticleMapper.delete(id);
	}

	@Override
	public int deleteBatch(Integer[] ids){
		return dfArticleMapper.deleteBatch(ids);
	}

	@Override
	public List<DfArticleVo> selectNoCommentArticle() {
		return dfArticleMapper.selectNoCommentArticle();
	}

	@Override
	public void updateCount(Integer id) {
		dfArticleMapper.updateCount(id);
	}

	@Override
	public DfArticleVo queryDetail(Integer id) {

		DfArticleVo articleVo = dfArticleMapper.queryDetail(id);
		articleVo.setCommentCount(dfArticleMapper.queryCommentCount(articleVo.getId()));
		articleVo.setLikeCount(dfArticleMapper.queryLikeCount(articleVo.getId()));
		String content = articleVo.getContent();
		String reg = "<img[^>]*>";
		Pattern pattern = Pattern.compile(reg);
		Matcher matcher = pattern.matcher(content);
		while (matcher.find()) {
			String img = matcher.group();
			content = content.replace(img,"");
		}
		int m = content.length() / 200;
		if(m > 5){
			articleVo.setTakeAway(String.format("此文章阅读大约需要 %d 分钟,请调整到舒服的阅读姿势",m));
		}

		return articleVo;
	}

	@Override
	public Integer queryCommentCount(Integer id) {
		return dfArticleMapper.queryCommentCount(id);
	}

	@Override
	public Integer queryLikeCount(Integer id) {
		return dfArticleMapper.queryLikeCount(id);
	}

	@Override
	public List<DfArticleVo> selectTop() {

		List<DfArticleVo> articleVos = dfArticleMapper.selectTop();
		articleVos.forEach(articleVo ->{
			try {
				int commentCount = articleVo.getCommentCount();
				int likeCount = articleVo.getLikeCount();
				int count = articleVo.getCount();
				SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
				Date nowDate = sf.parse(sf.format(new Date()));
				Date createDate = sf.parse(sf.format(articleVo.getCreateTime()));
				long nowTime = nowDate.getTime();
				long createTime = createDate.getTime();
				int minutes = (int) ((nowTime - createTime) / (1000 * 60));
				double hot = ((commentCount * 1 + likeCount * 0.5 + count * 0.1) * Math.exp(-0.8 * minutes));
				articleVo.setHot(Double.valueOf((hot + "").substring(0,5)));

			}catch (Exception e){

			}
		});

		return articleVos.stream().sorted(Comparator.comparing(DfArticleVo::getHot).reversed()).collect(Collectors.toList()).subList(0,5);

	}




	@Override
	public List<DfArticleVo> esSearch(String value) {

		List<ArticleBean> search = esSearchService.search(value);
		List<DfArticleVo> articleBeanList = new ArrayList<>();
		if(search != null)
			search.forEach( articleBean -> {
				DfArticleVo articleVo = this.queryDetail(articleBean.getId());
				articleVo.setTitle(articleBean.getTitle());
				articleVo.setContent(articleBean.getContent());
				articleBeanList.add(articleVo);
			});

		return articleBeanList;
	}

	/**
	 * 对double数据进行取精度.
	 * <p>
	 * For example: <br>
	 * double value = 100.345678; <br>
	 * double ret = round(value,4,BigDecimal.ROUND_HALF_UP); <br>
	 * ret为100.3457 <br>
	 *
	 * @param value
	 *            double数据.
	 * @param scale
	 *            精度位数(保留的小数位数).
	 * @param roundingMode
	 *            精度取值方式.
	 * @return 精度计算后的数据.
	 */
	public static double round(double value, int scale, int roundingMode) {
		BigDecimal bd = new BigDecimal(Double.toString(value));
		bd = bd.setScale(scale, roundingMode);
		double d = bd.doubleValue();
		bd = null;
		return d;
	}

}
